using System;
using Cinemachine;
using UnityEngine;
using Utils.FileFolderModule;
using Utils.JsonModule;

public class PlayerController : MonoBehaviour
{
    private Player player;

    private Rigidbody2D _rigidbody2D;
    private Animator animator;
    private SpriteRenderer spriteRenderer;

    private float speed = 5f;
    private float x;
    private float y;
    private static readonly int move = Animator.StringToHash("move");
    Quaternion forward = Quaternion.Euler(0, 0, 0);
    Quaternion backward = Quaternion.Euler(0, 180, 0);

    public Player Player => player;

    public float searchEnemyRange = 300.0f;

    void Awake()
    {
        _rigidbody2D = GetComponent<Rigidbody2D>();
    }

    private void OnEnable()
    {
#if UNITY_ANDROID
        EasyJoystick.On_JoystickMoveEnd += OnJoystickMoveEnd;
        EasyJoystick.On_JoystickMove += OnJoystickMove;
#endif
    }

    private void OnDisable()
    {
#if UNITY_ANDROID
        EasyJoystick.On_JoystickMoveEnd -= OnJoystickMoveEnd;
        EasyJoystick.On_JoystickMove -= OnJoystickMove;
#endif
    }

    private void OnDestroy()
    {
#if UNITY_ANDROID
        EasyJoystick.On_JoystickMoveEnd -= OnJoystickMoveEnd;
        EasyJoystick.On_JoystickMove -= OnJoystickMove;
#endif
    }

    void Update()
    {
#if UNITY_STANDALONE_WIN
        Move();
#endif
        Die();
    }

    public void Init()
    {
        animator = GetComponentInChildren<Animator>();
        player = GetComponentInChildren<Player>();
        spriteRenderer = player.transform.GetComponent<SpriteRenderer>();

        try
        {
            Knight knight = JsonHandler.GetObjectFromJson<Knight>(FilePathConfigue.KnightData);
            player.hp = knight.hp;
            player.maxHp = knight.hp;
            player.mp = knight.mp;
            player.maxMp = knight.mp;
            player.arm = knight.arm;
            player.maxArm = knight.arm;
        }
        catch (Exception e)
        {
            string knightJson = JsonHandler.GetJsonFromObject(new Knight());
            FileHandler.ReWriteFile(FilePathConfigue.KnightData, knightJson);
            Knight knight = JsonHandler.GetObjectFromJson<Knight>(FilePathConfigue.KnightData);
            player.hp = knight.hp;
            player.maxHp = knight.hp;
            player.mp = knight.mp;
            player.maxMp = knight.mp;
            player.arm = knight.arm;
            player.maxArm = knight.arm;
        }

        if (GameController.Instance().archiveCtr.TempLevelData.hp != 0)
        {
            player.hp = GameController.Instance().archiveCtr.TempLevelData.hp;
            player.mp = GameController.Instance().archiveCtr.TempLevelData.mp;
        }
    }

    public void CreatePlayer()
    {
        GameController.Instance().archiveCtr.levelData.player = PrefabRoot.knight;
    }

    private void Move()
    {
        if (animator.GetBool("die") || GameController.Instance().FSM.CurPlayerState == PlayerState.Die)
        {
            _rigidbody2D.velocity = Vector2.zero;
            return;
        }

        x = Input.GetAxis("Horizontal");
        y = Input.GetAxis("Vertical");
        if (Math.Abs(x) > 0.0001 || Math.Abs(y) > 0.0001) animator.SetBool(move, true);
        else animator.SetBool(move, false);

        if (GameController.Instance().FSM.CurPlayerState == PlayerState.NotFight)
        {
            if (x > 0.0001) spriteRenderer.transform.localRotation = forward;
            else if (x < -0.0001) spriteRenderer.transform.localRotation = backward;
        }

        _rigidbody2D.velocity = new Vector2(x, y) * speed;
    }

    public void SetPosition(Vector3 pos)
    {
        transform.position = pos;
    }

    public void ChangeForwardByNearestEnemy(Vector3 enemy, float distance)
    {
        if (searchEnemyRange >= distance)
        {
            GameController.Instance().FSM.CurPlayerState = PlayerState.Fight;
            GameController.Instance().weaponCtr.Weapon.UpdateLookAt(enemy);
            if (transform.position.x > enemy.x)
            {
                spriteRenderer.transform.localRotation = backward;
            }
            else if (transform.position.x < enemy.x)
            {
                spriteRenderer.transform.localRotation = forward;
            }
        }
        else
        {
            GameController.Instance().FSM.CurPlayerState = PlayerState.NotFight;
        }
    }

    public void UpdateHPMPLevelData()
    {
        GameController.Instance().archiveCtr.TempLevelData.hp = (int) player.hp;
        GameController.Instance().archiveCtr.TempLevelData.mp = (int) player.mp;
    }

    void OnJoystickMoveEnd(MovingJoystick joystick)
    {
        if (joystick.joystickName.Equals("PlayerJoystick"))
        {
            _rigidbody2D.velocity = Vector2.zero;
            animator.SetBool(move, false);
        }
    }

    void OnJoystickMove(MovingJoystick joystick)
    {
        if (!joystick.joystickName.Equals("PlayerJoystick") ||
            GameController.Instance().FSM.CurPlayerState == PlayerState.Die) return;
        float joystickX = joystick.joystickAxis.x;
        float joystickY = joystick.joystickAxis.y;

        if (joystickX != 0 || joystickY != 0)
        {
            if (GameController.Instance().FSM.CurPlayerState == PlayerState.NotFight)
            {
                if (joystickX > 0) spriteRenderer.transform.localRotation = forward;
                else if (joystickX < -0) spriteRenderer.transform.localRotation = backward;
            }

            _rigidbody2D.velocity = new Vector2(joystickX, joystickY) * speed;
            animator.SetBool(move, true);
        }
    }

    void Die()
    {
        if (GameController.Instance().FSM.CurPlayerState != PlayerState.Die)
            return;
        _rigidbody2D.velocity = Vector2.zero;
    }
}